home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / VideoToolbox 97.08.16 / VideoToolboxSources / Seconds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-09  |  5.2 KB  |  152 lines  |  [TEXT/CWIE]

  1. /*
  2. Seconds.c
  3.  
  4.     s=Seconds();
  5. returns the number of seconds (as a double, with 20 µs or better
  6. accuracy) since the computer started up.
  7.  
  8. If possible, we use the new UpTime routine, which uses the PPC's
  9. internal clock to get an accurate time with 20 nanosecond or better
  10. precision, but it's only available on PCI PowerMacs. Otherwise we use
  11. the Microseconds routine, which has 20 microseconds precision, and is
  12. part of Mac OS 7.
  13.  
  14. UpTime offers stable timing even when interrupts are blocked (e.g. by
  15. calls to cscSetEntries). It is my unconfirmed impression that
  16. Microseconds advances at a reduced rate when we're repeatedly calling
  17. cscSetEntries on my PowerMac 7500.
  18.  
  19. Microseconds() is documented in "Inside Mac: OS Utilities".
  20.  
  21. UpTime is documented in "Designing PCI Cards and Drivers for Power
  22. Macintosh Computers".
  23.  
  24. UpTime and Microseconds are briefly described in Martin Minow (1996)
  25. Timing on the Macintosh, develop 26.
  26. <http://devworld.apple.com/dev/techsupport/develop/issue26/minow.html>
  27.  
  28. The shared library DriverServicesLib must be weak linked with this
  29. project, when compiling for ppc; it's not needed when compiling for 68k.
  30.  
  31. 4/28/97 The latest word from Apple is "The UpTime call will not be
  32. implemented on earlier PowerPCs under Tempo (Mac OS 8). That was the
  33. plan under Maxwell, but is no longer being considered."
  34.  
  35. REFERENCE:
  36. TechNote 1083 Weak-linking to a Code Fragment Manager-based shared library
  37. http://devworld.apple.com/dev/technotes/tn/tn1083.html
  38.  
  39. HISTORY:
  40. 5/8/96    dgp    Wrote the MEX routine Secs.c.
  41.                 dhb    Changed name to GetSecs, cosmetic editing.
  42.                 dgp Use UpTime if available.
  43. 6/6/96    dgp    Omit DriverServicesLib calls when compiling for 68K.
  44. 1/26/97    dgp minor changes to allow successful 68K compile.
  45. 1/26/97    dgp extracted most of the code from GetSecs.c to create this new VideoToolbox
  46.                         Seconds.c, to make this good timebase more widely available.
  47. 2/9/97    dgp    corrected function name in error message.
  48. 3/19/97    dgp    minor tuning of the floating point arithmetic
  49. 7/9/97    dgp    Simplified the test for availability of UpTime, based on TN1083.
  50. */
  51. #include "VideoToolbox.h"
  52. #if GENERATINGCFM
  53.     #ifndef __CODEFRAGMENTS__
  54.         #include <CodeFragments.h>
  55.     #endif
  56. #endif
  57.  
  58. typedef UnsignedWide AbsoluteTime;    // Types.h
  59. typedef UnsignedWide Nanoseconds;    // DriverServices.h
  60. extern AbsoluteTime UpTime(void);    // DriverServices.h
  61. extern Nanoseconds AbsoluteToNanoseconds(AbsoluteTime absoluteTime);// DriverServices.h
  62.  
  63. double Seconds(void)
  64. {
  65.     static Boolean firstTime=1,upTimeAvailable=0;
  66.     double s;
  67.  
  68.     if(firstTime){
  69.         long version;
  70.  
  71.         // Make sure Microseconds trap is available.
  72.         Gestalt(gestaltSystemVersion,&version);
  73.         if(version<0x700)PrintfExit("%s: your System is too old; we need at least System 7.\n",__FILE__);
  74.  
  75.         // Is UpTime available?
  76.         // The UpTime glue is in the DriverServicesLib shared library, which is
  77.         // weak-linked, so we must load it before using it. If we fail, 
  78.         // we mustn't try to access the library's exports.
  79.         // upTimeAvailable=IsDriverServicesLibAvailable();
  80.         // In principle 68K code could call the PPC UpTime routine, but that would
  81.         // require going through a UPP, which I haven't bothered with here. So we 
  82.         // play safe and only call UpTime from PPC code. This restriction won't affect
  83.         // fat applications since they always run native.
  84.         #if GENERATINGCFM && GENERATINGPOWERPC
  85.             upTimeAvailable= (Ptr)UpTime!=(Ptr)kUnresolvedCFragSymbolAddress;
  86.         #else
  87.             upTimeAvailable=0;
  88.         #endif
  89.         firstTime=0;
  90.     }
  91.     if(upTimeAvailable){
  92.         #if GENERATINGCFM && GENERATINGPOWERPC
  93.             AbsoluteTime elapsedTime;
  94.             Nanoseconds elapsedNanoseconds;   // an UnsignedWide integer
  95.  
  96.             elapsedTime=UpTime();
  97.             elapsedNanoseconds=AbsoluteToNanoseconds(elapsedTime);
  98.             // NOTE: 4294967296.0 == (double)0x10000*0x10000
  99.             s=elapsedNanoseconds.lo+4294967296.0*elapsedNanoseconds.hi;
  100.             s/=1e9;
  101.         #endif
  102.     }else{
  103.         UnsignedWide microTicks;
  104.  
  105.         Microseconds(µTicks);
  106.         s=microTicks.lo+4294967296.0*microTicks.hi;
  107.         s*=1e-6;
  108.     }
  109.     return s;
  110. }
  111.  
  112. /*
  113. Boolean IsDriverServicesLibAvailable(void)
  114. {
  115.     long error;
  116.     Boolean isAvailable;
  117.  
  118.     if(1){
  119.         // This extra test isn't strictly necessary. 
  120.         // However, calling Gestalt is fast, whereas calling GetSharedLibrary requires
  121.         // a disk access, so we only call GetSharedLibrary if we expect it to succeed. 
  122.         Boolean pci;
  123.         long value,version;
  124.         #define gestaltNameRegistryVersion 'nreg'    // support old Gestalt.h header
  125.  
  126.         error=Gestalt(gestaltNameRegistryVersion,&value);
  127.         pci=!error;    // are there PCI slots?
  128.         Gestalt(gestaltSystemVersion,&version);
  129.         isAvailable=pci;
  130.     }
  131.     #if GENERATINGPOWERPC && CFMSYSTEMCALLS
  132.         if(isAvailable){
  133.             // The DriverServicesLib shared library is
  134.             // weak-linked, so we must load it before using it. If we fail, 
  135.             // we mustn't try to access the library's exports.
  136.             CFragConnectionID connID;
  137.             Ptr mainAddr;
  138.             Str255 errorMessage;
  139.             long value;
  140.             
  141.             error=Gestalt(gestaltCFMAttr,&value);    // Code Fragment Manager?
  142.             if(!error)error=GetSharedLibrary((ConstStr63Param)"\pDriverServicesLib"
  143.                 ,kAnyCFragArch,kFindCFrag,&connID,&mainAddr,errorMessage);
  144.             isAvailable=!error;
  145.             if(error)printf("WARNING: IsDriverServicesLibAvailable: GetSharedLibrary error=%ld, %s\n",(long)error,p2cstr(errorMessage));
  146.         }
  147.     #else
  148.         isAvailable=0;
  149.     #endif
  150.     return isAvailable;
  151. }
  152. */